import React, {useEffect, useRef, useState} from "react";
import {Dropdown, Space} from 'antd';
import { DownOutlined } from '@ant-design/icons';
import {Enums, init as csRenderInit, RenderingEngine} from "@cornerstonejs/core";
import {wadouri} from '@cornerstonejs/dicom-image-loader';
import initCornerstoneDICOMImageLoader from '../utils/initCornerstoneDicomImageLoader.js';
import * as cornerstoneTools from '@cornerstonejs/tools';
import './index.css';
import { v4 as uuidv4 } from 'uuid';
import dicomParser from 'dicom-parser';
// import {addButtonToToolbar} from "../utils/addToggleButtonToToolbar";
import { saveAs } from 'file-saver';
import htmlDocx from 'html-docx-js/dist/html-docx';
import request from '../api/request.js'
import {removeAllAnnotations} from "@cornerstonejs/tools/dist/esm/stateManagement/annotation/annotationState";
import { Layout, Button, Input, Slider, Select, List, message, Upload, Spin, Image, Tabs } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import {annotation} from "@cornerstonejs/tools";

// addToggleButtonToToolbar = undefined
const ACCEPTED_EXTENSIONS = ['zip'];

console.log(1);
const { Header, Sider, Content } = Layout;

const {ViewportType, Events} = Enums;
const { selection, visibility,state } = annotation;
const renderingEngineId = 'myRenderingEngine';
const viewportId = 'CT_STACK';

const windowWidth = 1500;
const windowCenter = -450;

const lower = windowCenter - windowWidth / 2.0;
const upper = windowCenter + windowWidth / 2.0;

const ctVoiRange = {lower, upper};

const tools = [
    {
        tool: cornerstoneTools.WindowLevelTool,
        name: cornerstoneTools.WindowLevelTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.PanTool,
        name: cornerstoneTools.PanTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.ZoomTool,
        name: cornerstoneTools.ZoomTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.StackScrollMouseWheelTool,
        name: cornerstoneTools.StackScrollMouseWheelTool.toolName
    },
    {
        tool: cornerstoneTools.LengthTool,
        name: cornerstoneTools.LengthTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    },
    {
        tool: cornerstoneTools.ProbeTool,
        name: cornerstoneTools.ProbeTool.toolName,
        mouse: cornerstoneTools.Enums.MouseBindings.Primary
    }
];

const wwwcOptions = [
    { windowWidth: 1500, windowCenter: -450 }, // 原始窗
    { windowWidth: 1500, windowCenter: -600 }, // 肺窗
    { windowWidth: 1500, windowCenter: 300 }, // 骨窗
    { windowWidth: 350, windowCenter: 40 }, // 纵隔窗
    { windowWidth: 1700, windowCenter: -500 }, // 肺窗2
    { windowWidth: 400, windowCenter: 40 }, // 腹窗
    { windowWidth: 600, windowCenter: 300 }, // 血管造影
    { windowWidth: 80, windowCenter: 40 }, // 脑窗
  ];

const menuTools = [
    {
        label: '长度测量',
        key: cornerstoneTools.LengthTool.toolName,
    },
    {
        label: 'CT值测量',
        key: cornerstoneTools.ProbeTool.toolName,
    }
];

const columnNames = ["腺癌", "鳞癌", "炎症", "良性其他", "小细胞癌"];

let docImageData = {};

/**
 * demo按照file加载的模式
 */
function StackImages() {
    let isScrolling = false;

    let toolGroup = useRef(null);

    let pointRectShowStateRef = useRef('hidden');

    let docImageViewport = useRef(null);

    const [messageApi, contextHolder] = message.useMessage();
    let selectedItemIndex = useRef(null);
    const [uploadFileList, setUploadFileList] = useState([]);
    const uploadRef = useRef(null); // 使用 useRef 创建一个引用

    const [loading, setLoading] = React.useState(false);
    let txtRef = useRef(null);
    let sortDataRef = useRef(null);
    let maxColumnsRef = useRef([]);
    let csvFileRef = useRef([]);
    let [dicom, setDicom] = useState([]);
    let [zipFile, setZipFile] = useState(null);
    let [viewport, setViewport] = useState(null);
    let [dicomBasicInfo, setDicomBasicInfo] = useState(null);
    let [currentImageIdIndex, setCurrentImageIdIndex] = useState(0);
    let [currentCsvIndex, setCurrentCsvIndex] = useState(-1);
    let [pointRectShowState, setPointRectShowState] = useState('hidden');   // show hidden

    useEffect(() => {
        const content = document.getElementById('content');
        if (!content.children || (content.children.length === 0)) {
            setup();
        }
    }, []);

    useEffect(() => {
        pointRectShowStateRef.current = pointRectShowState;
    }, [pointRectShowState]);

    const setup = async () => {
        // dom
        const content = document.getElementById('content');
        const element = document.createElement('div');
        element.id = 'cornerstone-element';
        element.style.width = '100%';
        element.style.height = '100%';
        content.appendChild(element);

        // init
        initCornerstoneDICOMImageLoader();
        await csRenderInit({
            gpuTier: {
                tier: 0
            }
        });
        const renderingEngine = new RenderingEngine(renderingEngineId);
        const viewportInput = {
            viewportId,
            type: ViewportType.STACK,
            element
        };
        renderingEngine.enableElement(viewportInput);
        setViewport(renderingEngine.getViewport(viewportId));

        initTools();
    };


    // const addButtonToToolbar = () => {
    //     const annoState = (state.getAnnotationManager())
    //     const annotationUIDs = selection.getAnnotationsSelected();
    //     console.log("state");
    //     console.log(typeof annoState.annotations);
    //     const keys = Object.keys(annoState.annotations)[0];
    //     console.log(keys);
    //     console.log(annoState.annotations[keys]);
    //     const allAnnoState = annoState.annotations[keys];
    //     console.log("allAnnoState",allAnnoState)
    //     console.log("Id",viewport.currentImageIdIndex)
    //     const currentId = "dicomfile:"+ viewport.currentImageIdIndex;
    //     console.log(currentId)
    //     console.log(allAnnoState['Probe'][5].data.cachedStats)
    //
    //     // for (let i = 0; i < allAnnoState.length; i ++){
    //     //     if (allAnnoState[i])
    //     // }
    // }
    const loadImageStack = async (imageIds) => {
        // stack render
        await viewport.setStack(imageIds);
        viewport.setProperties({voiRange: ctVoiRange});
        viewport.resize();
        viewport.render();

        // load dicom info
        const image = viewport.csImage;
        const patientName = image.data.string('x00100010') || 'N/A';
        const patientID = image.data.string('x00100020') || 'N/A';
        const patientAge = image.data.string('x00101010') || 'N/A';
        const patientSex = image.data.string('x00100040') || 'N/A';
        const patientStudyDate = image.data.string('x00080020') || 'N/A';
        setDicomBasicInfo({patientName, patientID, patientAge, patientSex, patientStudyDate});
        // add event listener
        viewport.element.addEventListener(Events.IMAGE_RENDERED, onImageRender);
        window.addEventListener('resize', handleResize);
    };

    const handleResize = () => {
        viewport.resize();
        viewport.render();
    };

    const parseTXT = (contents) => {
        const lines = contents.split('\n');
        const spacingLine = lines[0];
        const spacing = spacingLine.match(/Spacing=\(([^)]+)\)/)?.[1].split(',').map(Number) || [];
      
        const parsedData = {
          spacing: spacing,
          slices: [],
        };
      
        for (let i = 2; i < lines.length; i++) {
          const line = lines[i].trim();
          if (!line) {
            continue;
          }
          const [slice, leftX, leftY, rightX, rightY, centerPoint, width, height] = line.split(/\s+/);
          const [centerX, centerY] = centerPoint.replace(/[()]/g, '').split(',').map(Number);
      
          parsedData.slices.push({
            slice: Number(slice),
            leftX: Number(leftX),
            leftY: Number(leftY),
            rightX: Number(rightX),
            rightY: Number(rightY),
            centerPoint: { x: centerX, y: centerY },
            width: Number(width),
            height: Number(height),
          });
        }
      
        return parsedData;
      };
      
    // const uploadTxt = async () => {
    //     try {
    //         await request({
    //             url: "/get_txt",
    //             method: "GET"
    //           }).then((res) => {
    //             const text = res;
    //             const txt = parseTXT(text);
    //             txtRef.current = txt;
    //             // 从大到小排列
    //             // const sortedSlices = txt.slices.slice().sort((a, b) => b.slice - a.slice);
    //             sortDataRef.current = txt;
    //         });
    //     } catch (error) {
    //         messageApi.error('结节信息请求发生错误①', error);
    //     }
    // };
    
    const uploadTxt = async () => {
        const text = `Spacing=(0.705078, 0.705078, 0.625)
        Slice		Left X		Left Y		Right X		Right Y		Center Point		Width(mm)		Height(mm)
        133			125				366				142				382				(133,374)				11.99				11.28
        139			306				363				319				376				(312,369)				9.17				9.17
        141			135				339				169				374				(152,356)				23.97				24.68
        147			156				331				168				343				(162,337)				8.46				8.46
        154			179				355				194				371				(186,363)				10.58				11.28
        160			108				366				120				379				(114,372)				8.46				9.17
        167			112				206				124				218				(118,212)				8.46				8.46
        173			114				354				138				378				(126,366)				16.92				16.92
        180			125				314				141				330				(133,322)				11.28				11.28
        181			205				329				215				339				(210,334)				7.05				7.05
        182			125				314				142				331				(133,322)				11.99				11.99
        187			131				314				147				329				(139,321)				11.28				10.58
        192			125				369				141				385				(133,377)				11.28				11.28
        194			137				311				155				329				(146,320)				12.69				12.69
        195			198				326				207				335				(202,330)				6.35				6.35
        196			399				270				410				281				(404,275)				7.76				7.76
        201			143				367				173				397				(158,382)				21.15				21.15
        205			111				380				122				391				(116,385)				7.76				7.76
        206			143				361				176				394				(159,377)				23.27				23.27
        210			101				370				114				383				(107,376)				9.17				9.17
        211			397				281				407				291				(402,286)				7.05				7.05
        229			391				296				402				307				(396,301)				7.76				7.76
        238			104				374				114				385				(109,379)				7.05				7.76
        250			150				181				161				192				(155,186)				7.76				7.76
        251			84				325				112				353				(98,339)				19.74				19.74
        260			91				329				112				350				(101,339)				14.81				14.81
        276			89				248				99				258				(94,253)				7.05				7.05
        282			94				346				105				357				(99,351)				7.76				7.76
        287			368				232				379				242				(373,237)				7.76				7.05
        288			90				253				98				261				(94,257)				5.64				5.64
        289			375				344				384				353				(379,348)				6.35				6.35
        293			104				250				123				269				(113,259)				13.40				13.40
        298			363				356				373				366				(368,361)				7.05				7.05
        308			94				330				105				341				(99,335)				7.76				7.76
        311			362				359				371				367				(366,363)				6.35				5.64
        317			360				362				368				370				(364,366)				5.64				5.64
        325			116				209				126				220				(121,214)				7.05				7.76
        333			376				261				385				269				(380,265)				6.35				5.64
        342			361				353				369				361				(365,357)				5.64				5.64
        363			293				389				303				398				(298,393)				7.05				6.35
        365			107				342				117				351				(112,346)				7.05				6.35
        367			316				378				327				389				(321,383)				7.76				7.76
        378			104				269				113				279				(108,274)				6.35				7.05
        384			147				220				164				238				(155,229)				11.99				12.69
        386			151				357				160				366				(155,361)				6.35				6.35
        388			108				279				120				291				(114,285)				8.46				8.46
        392			293				255				304				266				(298,260)				7.76				7.76
        394			347				273				355				281				(351,277)				5.64				5.64
        395			176				359				186				368				(181,363)				7.05				6.35
        398			296				259				308				271				(302,265)				8.46				8.46
        398			289				369				298				378				(293,373)				6.35				6.35
        401			345				305				356				316				(350,310)				7.76				7.76
        `;
        const txt = parseTXT(text);
        txtRef.current = txt;
        console.log('txtRef', txtRef.current);
        console.log('TXT')
        console.log(txt)
        // 从大到小排列
        const sortedSlices = txt.slices.slice().sort((a, b) => a.slice - b.slice);
        console.log('sortedSlices')
        console.log(sortedSlices);
        sortDataRef.current = sortedSlices
        console.log('sortDataRef', sortDataRef.current);
    };

    // const uploadCsv = async () => {
    //     try {
    //         await request({
    //             url: "/get_csv",
    //             method: "GET"
    //           }).then((res) => {
    //             const data = res;
    //             const trimmedData = data.slice(1, -1).map(row => row.slice(1));
    //             const formattedData = trimmedData.map(row => 
    //                 row.map(value => {
    //                     const num = Number(value);
    //                     return num.toFixed(10); // 使用 toFixed(10) 格式化为 10 位小数
    //                 })
    //             );
    //             csvFileRef.current = formattedData;
    //             const maxCols = trimmedData.map(row => {
    //                 let maxVal = Number.MIN_VALUE;
    //                 let maxIndex = -1;
    //                 row.forEach((value, index) => {
    //                 const floatValue = parseFloat(value);
    //                 if (floatValue > maxVal) {
    //                     maxVal = floatValue;
    //                     maxIndex = index;
    //                 }
    //                 });
    //                 return columnNames[maxIndex];
    //             });
    //             maxColumnsRef.current = maxCols;
    //         });
    //     } catch (error) {
    //         messageApi.error('结节信息请求发生错误②', error);
    //     }
    // }

    const uploadCsv = async () => {
        const data = [
            [
                "",
                "0",
                "1",
                "2",
                "3",
                "4"
            ],
            [
                "0",
                "1.6814969e-05",
                "0.43286294",
                "0.02283739",
                "0.0020410111",
                "0.5422419"
            ],
            [
                "1",
                "4.036417e-09",
                "1.7340311e-05",
                "0.99996483",
                "1.7683313e-05",
                "1.6561458e-07"
            ],
            [
                "2",
                "1.4228116e-08",
                "0.9999912",
                "8.869274e-06",
                "4.5786347e-08",
                "1.7068161e-09"
            ],
            [
                "3",
                "2.321017e-05",
                "0.01246444",
                "0.0057162126",
                "0.0001157459",
                "0.9816804"
            ],
            [
                "4",
                "1.5739768e-09",
                "0.99934465",
                "0.0005997626",
                "1.1230688e-07",
                "5.5519457e-05"
            ],
            [
                "5",
                "2.9550876e-07",
                "1.2058941e-05",
                "0.99997854",
                "8.797439e-06",
                "2.199579e-07"
            ],
            [
                "6",
                "1.05599474e-10",
                "9.940225e-08",
                "0.99999917",
                "7.1892646e-07",
                "3.7564513e-10"
            ],
            [
                "7",
                "0.00083699386",
                "0.0012350312",
                "0.06227878",
                "0.0024935803",
                "0.9331556"
            ],
            [
                "8",
                "0.00018770141",
                "0.27095932",
                "0.72270036",
                "0.0022265248",
                "0.0039260658"
            ],
            [
                "9",
                "6.6773265e-07",
                "0.0032102289",
                "0.9842163",
                "0.00013586601",
                "0.01243702"
            ],
            [
                "10",
                "4.3346344e-09",
                "0.037742857",
                "0.9619102",
                "0.00033991513",
                "7.130691e-06"
            ],
            [
                "11",
                "0.0020356115",
                "1.1486971e-07",
                "0.9979632",
                "1.1022208e-06",
                "1.5675788e-10"
            ],
            [
                "12",
                "1.6921776e-05",
                "0.010991031",
                "0.90685916",
                "0.0821307",
                "2.073783e-06"
            ],
            [
                "13",
                "1.2162776e-07",
                "0.0716641",
                "0.92163837",
                "0.006696645",
                "7.078917e-07"
            ],
            [
                "14",
                "6.550712e-08",
                "9.46346e-05",
                "0.9985669",
                "0.0013205705",
                "1.7685727e-05"
            ],
            [
                "15",
                "3.4394177e-06",
                "0.036842976",
                "0.9585933",
                "0.0045596357",
                "7.021428e-07"
            ],
            [
                "16",
                "4.392215e-09",
                "2.707672e-05",
                "0.9997949",
                "0.00017798538",
                "7.401332e-08"
            ],
            [
                "17",
                "1.2025005e-05",
                "0.00027774766",
                "0.9987538",
                "0.00050920097",
                "0.00044723487"
            ],
            [
                "18",
                "7.2057315e-07",
                "0.1268924",
                "0.87308776",
                "1.6937978e-05",
                "2.206866e-06"
            ],
            [
                "19",
                "1.320332e-11",
                "1.1158376e-06",
                "0.999992",
                "5.5856613e-06",
                "1.2540853e-06"
            ],
            [
                "20",
                "2.4150168e-07",
                "6.223118e-05",
                "0.9999368",
                "5.44971e-07",
                "1.3056595e-07"
            ],
            [
                "21",
                "0.06883021",
                "5.9849896e-07",
                "0.9310445",
                "1.1143009e-05",
                "0.00011350802"
            ],
            [
                "22",
                "1.0339564e-10",
                "2.2195454e-11",
                "1.0",
                "1.2501976e-10",
                "2.0061217e-11"
            ],
            [
                "23",
                "0.3112519",
                "0.111242846",
                "0.5742363",
                "8.397268e-06",
                "0.0032605517"
            ],
            [
                "24",
                "9.183655e-12",
                "4.373214e-06",
                "0.99999547",
                "1.1820578e-07",
                "2.9485376e-08"
            ],
            [
                "25",
                "0.063635185",
                "0.0011994401",
                "0.93355274",
                "0.0010243682",
                "0.000588271"
            ],
            [
                "26",
                "0.035461005",
                "0.00031678742",
                "0.9562363",
                "0.006350085",
                "0.0016358197"
            ],
            [
                "27",
                "9.685837e-06",
                "4.331404e-05",
                "0.9999291",
                "3.4848897e-06",
                "1.4465034e-05"
            ],
            [
                "28",
                "2.099777e-10",
                "2.5912941e-08",
                "0.99999964",
                "3.070702e-07",
                "2.0386954e-12"
            ],
            [
                "29",
                "5.7630425e-09",
                "0.5574112",
                "0.44258574",
                "1.378635e-08",
                "3.0851834e-06"
            ],
            [
                "30",
                "1.3317162e-05",
                "0.0040751314",
                "0.99577713",
                "7.1872223e-06",
                "0.00012718521"
            ],
            [
                "31",
                "3.233159e-11",
                "6.8711124e-05",
                "0.99993086",
                "3.070438e-07",
                "1.00560584e-07"
            ],
            [
                "32",
                "7.577764e-07",
                "0.0061870716",
                "0.99363637",
                "1.2203771e-05",
                "0.00016361011"
            ],
            [
                "33",
                "0.042243283",
                "0.0013160158",
                "0.955824",
                "3.2158567e-07",
                "0.0006163708"
            ],
            [
                "34",
                "7.316305e-06",
                "0.0027127536",
                "0.984641",
                "0.00025278615",
                "0.01238595"
            ],
            [
                "35",
                "0.05507427",
                "0.006295434",
                "0.8531958",
                "0.060569566",
                "0.02486494"
            ],
            [
                "36",
                "1.7089425e-08",
                "0.21243438",
                "0.7857461",
                "0.0018193995",
                "1.2503696e-07"
            ],
            [
                "37",
                "4.6065367e-07",
                "1.3420997e-05",
                "0.9999721",
                "1.3295134e-05",
                "7.408453e-07"
            ],
            [
                "38",
                "2.0497325e-06",
                "3.2214193e-05",
                "0.99991226",
                "4.5370627e-05",
                "8.150354e-06"
            ],
            [
                "39",
                "0.15526472",
                "0.0024801588",
                "0.4190123",
                "0.013555134",
                "0.4096876"
            ],
            [
                "40",
                "0.20300671",
                "0.0018908026",
                "0.17765667",
                "0.004234813",
                "0.61321104"
            ],
            [
                "41",
                "0.99400216",
                "6.669488e-07",
                "3.6939033e-05",
                "0.0039025578",
                "0.0020575626"
            ],
            [
                "42",
                "0.0014388559",
                "0.0021009732",
                "0.92007995",
                "0.033212345",
                "0.04316783"
            ],
            [
                "43",
                "4.1485382e-07",
                "1.952866e-05",
                "0.9989987",
                "0.0008565125",
                "0.00012496597"
            ],
            [
                "44",
                "1.6020988e-11",
                "0.000615011",
                "0.9993832",
                "9.931163e-07",
                "8.693686e-07"
            ],
            [
                "45",
                "3.054208e-08",
                "0.0011106402",
                "0.99888355",
                "8.043636e-08",
                "5.755829e-06"
            ],
            [
                "46",
                "5.8688926e-10",
                "5.218448e-06",
                "0.99999475",
                "4.0536174e-10",
                "2.9005007e-10"
            ],
            [
                "47",
                "4.2078952e-08",
                "0.98269236",
                "0.017302107",
                "3.7244101e-06",
                "1.7120617e-06"
            ],
            [
                "48",
                "0.00026105586",
                "0.31980792",
                "0.54654366",
                "0.117652215",
                "0.015735166"
            ],
            [
                "49",
                "6.0087248e-12",
                "1.7748861e-11",
                "1.0",
                "1.346169e-10",
                "2.2188965e-12"
            ],
            [
                "50",
                "0.68593013",
                "0.0077484753",
                "0.18774375",
                "0.07958302",
                "0.038994662"
            ],
            [
                "51",
                "1.5326761e-09",
                "0.9873876",
                "0.012477208",
                "0.00011005674",
                "2.515005e-05"
            ],
            [
                "52",
                "0.9517833",
                "1.9224217e-06",
                "0.046398956",
                "0.0018156485",
                "2.170264e-07"
            ]
        ];
        const trimmedData = data.slice(1, -1).map(row => row.slice(1));
        const formattedData = trimmedData.map(row => 
            row.map(value => {
                const num = Number(value);
                return num.toFixed(10); // 使用 toFixed(6) 格式化为 6 位小数
            })
        );
        console.log(trimmedData);
        csvFileRef.current = formattedData;
        const maxCols = formattedData.map(row => {
            let maxVal = Number.MIN_VALUE;
            let maxIndex = -1;
            row.forEach((value, index) => {
            const floatValue = parseFloat(value);
            if (floatValue > maxVal) {
                maxVal = floatValue;
                maxIndex = index;
            }
            });
            return columnNames[maxIndex];
        });
        console.log("maxColumn", maxCols);
        maxColumnsRef.current = maxCols;
    }


    const onImageRender = () => {
        setCurrentImageIdIndex(viewport.currentImageIdIndex);
        if (pointRectShowStateRef.current === 'show') {
            drawRect();
        }
        isScrolling = false;
    };


    const initTools = () => {
        tools.forEach((v) => {
            cornerstoneTools.addTool(v.tool);
        })
        toolGroup.current = cornerstoneTools.ToolGroupManager.createToolGroup('myToolGroup');
        tools.forEach((v) => {
            toolGroup.current.addTool(v.name);
        })
        // 左键

        tools.forEach((v) => {
            if (v.mouse) {
                // 包含鼠标事件的工具
                toolGroup.current.setToolActive(v.name, {
                    bindings: [{mouseButton: v.mouse}]
                });
            } else {
                toolGroup.current.setToolActive(v.name);
            }
        })
        toolGroup.current.addViewport(viewportId, renderingEngineId);
    };

    const handleToolMenuClick = (info) => {
        tools.forEach((v) => {
            if (v.mouse && (v.mouse === cornerstoneTools.Enums.MouseBindings.Primary)) {
                toolGroup.current.setToolPassive(v.name);
            }
        })
        console.log(toolGroup.current);
        console.log(info.key);
        toolGroup.current.setToolActive(info.key, {
            bindings: [{mouseButton: cornerstoneTools.Enums.MouseBindings.Primary}]
        });
    };

    const toggleShowRect = () => {
        const next = pointRectShowState === 'show' ? 'hidden' : 'show';
        setPointRectShowState(next);
        if (next === 'show') {
            drawRect();
        } else {
            viewport.render();
        }
    };

    const drawRect = () => {
        if (!viewport) return;
        const context = viewport.canvas.getContext('2d');
        console.log("sortDataref",sortDataRef.current);
        console.log("txtRef",txtRef.current);
        const slices = sortDataRef.current;
        console.log("slices",slices);
        for(let i = 0; i < slices.length; i ++) {
            const item = slices[i];
            const slice = item.slice;
            const leftX = item.leftX;
            const leftY = item.leftY;
            const rightX = item.rightX;
            const rightY = item.rightY;
            if (slice === viewport.currentImageIdIndex) {
                context.strokeStyle = 'rgba(41, 198, 33, 1)';
                context.fillStyle = 'rgba(41, 198, 33, 1)';
                // 计算矩形的宽度和高度
                const width = Math.abs(leftX - rightX);
                const height = Math.abs(leftY - rightY);
                context.strokeRect(leftX, leftY, width, height)
                context.textAlign = 'left';
                context.font = '15px serif';
                context.fillText(maxColumnsRef.current[i], rightX + 3, rightY);
            }
        }
    };

    // const deletaAnnotations = () => {
    //     if (!viewport) return;
    //     const context = viewport.canvas;
    //     console.log(context);
    //
    // };
    const handleWWWC = (value) => {
        // wwwcOptions
        const lower = wwwcOptions[value].windowCenter - wwwcOptions[value].windowWidth / 2.0;
        const upper = wwwcOptions[value].windowCenter + wwwcOptions[value].windowWidth / 2.0;

        const ctVoiRange = {lower, upper};
        viewport.setProperties({voiRange: ctVoiRange})
        viewport.render();
    }

    
    const goToPage = (targetIndex) => {
        // Ensure that targetIndex is within valid range
        if (targetIndex < 0 || targetIndex >= viewport.imageIds.length) {
            return;
        }
        if (!viewport) return ;
        if (isScrolling) return ;
        if (targetIndex === viewport.currentImageIdIndex) return;
        isScrolling = true;
        const currentIndex = viewport.currentImageIdIndex;
        const delta = targetIndex - currentIndex;
        // 创建滚动选项对象
        const options = {
            delta: delta, // 滚动的增量
        };
        try {
            cornerstoneTools.utilities.scroll(viewport, options);
        } catch (error) {
            console.error('Error while scrolling:', error);
        }
    }

    const onClickpdf = async () => {
        // 创建包含图像的 HTML 字符串
        let htmlString = `
        <!DOCTYPE html>
        <html>
        <head>
            <style>
            body {
                font-family: Arial, sans-serif;
            }
            h1 {
                font-size: 30px;
                text-align: center;
            }
            h3 {
                text-align: center;
            }
            hr {
                border: 1px solid #000;
            }
            .patient-info {
                font-size: 14px;
            }
              .hr-dashed-fixed {
                border: 0;
                padding-top: 1px;
                /* for IE浏览器 */
                background: repeating-linear-gradient(to right, #a2a9b6 0px, #a2a9b6 4px, transparent 0px, transparent 10px);
                /* for 现代浏览器 */
                background: repeating-linear-gradient(to right, #a2a9b6 0 var(--dashed-filled, 4px), transparent 0 calc(var(--dashed-filled, 4px) + var(--dashed-open, 6px)));//传入变量来定义疏密
            }
            </style>
        </head>
        <body>
            <h1>肺部CT报告</h1>
            <hr class="hr-dashed-fixed" style="--dashed-filled: 8px; --dashed-open: 4px;"/>
            <div class="patient-info">
            <p>ID: ${dicomBasicInfo.patientID}</p>
            <p>姓名: ${dicomBasicInfo.patientName}</p>
            <p>年龄: ${dicomBasicInfo.patientAge}</p>
            <p>性别: ${dicomBasicInfo.patientSex}</p>
            <p>检查日期: ${dicomBasicInfo.patientStudyDate}</p>
            </div>
          <hr class="hr-dashed-fixed" style="--dashed-filled: 8px; --dashed-open: 4px;"/>
          <h3>
            报告详情
          </h3>
          `

        // 加入图片
        const docImages = await getDocImages();
        console.log('docImages', docImages);
        console.log('sortData', sortDataRef.current);
        console.log('csvFile', csvFileRef.current);
        
        // Create a map to store the corresponding sortData and maxColumns for each image
        const imageDataMap = new Map();

        for (let i = 0; i < sortDataRef.current.length; i++) {
            const item = sortDataRef.current[i];
            const imageId = item.slice; // 假设 sortData 中有 imageId 属性与 docImages 对应
            let probabilitiesString = "";

            if (!imageDataMap.has(imageId)) {
                imageDataMap.set(imageId, []);
            }
            const selectedData = csvFileRef.current[i];
            for (let j = 0; j < selectedData.length; j++) {
                probabilitiesString += `${columnNames[j]}: ${selectedData[j]}<br/>`;
            }
            
            imageDataMap.get(imageId).push({
                description: maxColumnsRef.current[i],
                width: item.width,
                height: item.height,
                probabilities: probabilitiesString
            });
        }
        console.log("imageDataMap", imageDataMap);

        for (let i = 0; i < docImages.length; i++) {
            const imageItem = docImages[i];
            // const len = viewport.imageIds.length
            const imageId = imageItem.slice; // 假设 docImages 中有 id 属性
            const imageData = imageDataMap.get(imageId) || [];
            console.log('i', i, imageItem, imageData);
        
            htmlString += `<img src="${imageItem.image}" alt="CT Image"/>`;
        
            for (let j = 0; j < imageData.length; j++) {
                const data = imageData[j];
                htmlString += `
                    <p>描述：${data.description} ${data.width}mm × ${data.height}mm
                    <br />
                    其他概率：${data.probabilities}
                    </p>
                    <br/>
                `;
            }
        }

        // 结尾
        htmlString += `
        <h4>影像所见：</h4>
        <br/>
        <h4>防范建议：</h4>
        <br/>
        </body>
        </html>
        `;
        // 使用 html-docx-js 将 HTML 字符串转换为 DOCX
        const blob = htmlDocx.asBlob(htmlString);
        saveAs(blob, `${dicomBasicInfo.patientID}肺部CT报告.docx`);
        
    }

    const onDocImageRender = () => {
        const context = docImageViewport.value.canvas.getContext('2d');
        const page = docImageViewport.value.currentImageIdIndex;
        for (let i = 0; i < sortDataRef.current.length; i++) {
            if (page === sortDataRef.current[i].slice)
            {
                const { leftX, leftY, rightX, rightY } = sortDataRef.current[i];
                context.strokeStyle = 'rgba(41, 198, 33, 1)';
                context.fillStyle = 'rgba(41, 198, 33, 1)';
                const width = Math.abs(leftX - rightX);
                const height = Math.abs(leftY - rightY);
                context.strokeRect(leftX, leftY, width, height);
            }
        }
        const data = docImageViewport.value.canvas.toDataURL('image/png');
        docImageData.resolve(data);
    }

    const getOneDocImage = (item) => {
        return new Promise(async (resolve, reject) => {
            docImageData = {
                resolve,
                data: null
            };
            docImageViewport.value.setImageIdIndex(item.slice);
            // drawRect(item.slice
            await drawRectSingle(item);
        })
    }

    const drawRectSingle = (item) => {
        const context = docImageViewport.value.canvas.getContext('2d');
        const slice = item.slice;
        const leftX = item.leftX;
        const leftY = item.leftY;
        const rightX = item.rightX;
        const rightY = item.rightY;
        if (slice === viewport.currentImageIdIndex) {
            context.strokeStyle = 'rgba(41, 198, 33, 1)';
            context.fillStyle = 'rgba(41, 198, 33, 1)';
            // 计算矩形的宽度和高度
            const width = Math.abs(leftX - rightX);
            const height = Math.abs(leftY - rightY);
            context.strokeRect(leftX, leftY, width, height)
            // context.textAlign = 'left';
            // context.font = '15px serif';
            // context.fillText(maxColumnsRef.current[item.index], rightX + 3, rightY);
        }
    }

    const getDocImages = () => {
        return new Promise(async (resolve, reject) => {
            const curFiles = dicom;
            const imageIds = [];
            for (let i = 0; i < curFiles.length; i++) {
                imageIds[i] = wadouri.fileManager.add(curFiles[i]);
            }
            const element = document.createElement('div');
            element.id = 'cornerstone-element-doc';
            element.style.width = '350px';
            element.style.height = '350px';
            element.style.visible = 'hidden';
            document.body.appendChild(element);
            const viewportId = 'CT_Stack_doc';
            const renderingEngine = new RenderingEngine("RenderingEngineDoc");
            const viewportInput = {
                viewportId,
                type: ViewportType.STACK,
                element
            };
            renderingEngine.enableElement(viewportInput);
            docImageViewport.value = renderingEngine.getViewport(viewportId);
            docImageViewport.value.element.addEventListener(Events.IMAGE_RENDERED, onDocImageRender);
            docImageViewport.value.setStack(imageIds);
            docImageViewport.value.setProperties({voiRange: ctVoiRange});

            const slices = sortDataRef.current;
            const result = [];
            const processedSlices = new Set();  // 用于跟踪已处理的slice页码
            for (let i = 0; i < slices.length; i++) {
                const item = slices[i];
                // 如果当前slice页码已处理，则跳过
                if (processedSlices.has(item.slice)) {
                    continue;
                }
                const image = await getOneDocImage(item);
                result.push({
                    index: i,
                    slice: item.slice,
                    image
                })
                // 标记当前slice页码为已处理
                processedSlices.add(item.slice);
            }
            docImageViewport.value.element.removeEventListener(Events.IMAGE_RENDERED, onDocImageRender);
            document.body.removeChild(element);
            resolve(result);
        })
    }

    const handleListItemClick = (item, index) => {
        selectedItemIndex.current = index;
        // setSelectedItemIndex(index);
        setCurrentCsvIndex(index);
        console.log(item, index, selectedItemIndex.current);
        goToPage(item.slice)
    }

    const parseDicomFile = (arrayBuffer) => {
        let result = 0;
        try {
          const byteArray = new Uint8Array(arrayBuffer);
          const dataSet = dicomParser.parseDicom(byteArray);
          const instanceNumber = dataSet.string('x00200013');
          result = instanceNumber;
        } catch (error) {
          console.error('Error parsing DICOM file:', error);
        //   setSeriesInstanceUID(null);
        }
        return result;
      };
    

    const onFileChange = async (event) => {
        // 先按照seriesInstance排序
        const file = event.target.files;
        if (!file) {
            return;
        }
        // 存储每个文件的 Instance Number 和文件本身
        const filesWithInstanceNumbers = [];
        for (let i = 0; i < file.length; i++) {
            const reader = new FileReader();
            const curFile = file[i];
            reader.onload = (event) => {
                const arrayBuffer = event.target.result;
                const instanceNumber = parseDicomFile(arrayBuffer);
                filesWithInstanceNumbers.push({ instanceNumber, file: curFile });

                // 如果已经处理完所有文件，则进行排序和获取文件列表
                if (filesWithInstanceNumbers.length === file.length) {
                    // 按 Instance Number 属性从小到大排序
                    filesWithInstanceNumbers.sort((a, b) => a.instanceNumber - b.instanceNumber);

                    // 获取排序后的文件列表
                    const sortedFiles = filesWithInstanceNumbers.map(item => item.file);

                    // 输出排序后的文件列表示例
                    // sortedFiles.forEach(sortedFile => {
                    //     console.log('Sorted File:', sortedFile.name);
                    //     // 这里可以进一步处理排序后的文件
                    // });
                    setDicom(sortedFiles);
        
                    const imageIds = [];
                    for (let i = 0; i < sortedFiles.length; i++) {
                        imageIds[i] = wadouri.fileManager.add(sortedFiles[i]);
                    }
                    loadImageStack(imageIds);
                }
            };
            reader.readAsArrayBuffer(curFile);
        }
    };

    // 上传文件
    const submitUpload = () => {
        setLoading(true);
        if (uploadRef.current) {
            const fileList = uploadRef.current.fileList;
            fileList.forEach(file => {
                upload({ file });
              });
        }
      };
    
      const handleExceed = (files) => {
        if (uploadRef.current) {
        //   uploadRef.current.clearFiles();
          const file = files[0];
          file.uid = uuidv4();
          uploadRef.current.handleStart(file);
        }
      };
    
      const beforeUpload = async (file) => {
        setZipFile(file);

        const extension = file.name.split('.').pop().toLowerCase();
    
        if (!ACCEPTED_EXTENSIONS.includes(extension)) {
          messageApi.error('仅支持zip格式的文件');
          return false;
        } else {
          const newUploadFile = {
            name: file.name,
            size: file.size,
            uploadPercentage: 0,
            uploadSpeed: "0 M/s",
            chunkList: [],
            file,
            uploadingStop: false,
          };
          setUploadFileList((prevList) => [...prevList, newUploadFile]);
        }
        return false;
      };
    
    
      const upload = ({ file }) => {
        const uploadFile = uploadFileList.find((uf) => uf.name === zipFile.name && uf.size === zipFile.size);
        if (uploadFile) {
          uploadChunk(zipFile, 1, uploadFile);
        }
      };
    
      const uploadChunk = async (file, index, uploadFile) => {
        if (!(file instanceof Blob || file instanceof File)) {
            console.error('Invalid file type. Expected a Blob or File.');
            return;
        }
        const chunkSize = 1024 * 1024 * 10; // 10mb
        const chunkTotal = Math.ceil(file.size / chunkSize);
        if (index <= chunkTotal) {
    
          const startTime = new Date().valueOf();
          const exit = uploadFile.chunkList.includes(index);

          if (!exit) {
            // 根据是否暂停，确定是否继续上传
            if (!uploadFile.uploadingStop) {
              const form = new FormData();
              const start = (index - 1) * chunkSize;
              const end = index * chunkSize >= file.size ? file.size : index * chunkSize;
              const chunk = file.slice(start, end);
    
              form.append("chunk", chunk);
              form.append("index", index);
              form.append("chunkTotal", chunkTotal);
              form.append("chunkSize", chunkSize);
              form.append("uuidName", uploadFile.uuidName);
              form.append("fileSize", file.size);
              form.append("fileName", file.name);
              form.append("tp", 1);
    
              try {
                await request({
                    url: "/upload/chunk",
                    method: "post",
                    data: form,
                  }).then((res) => {
                    // console.log(res);
                    const endTime = new Date().valueOf();
                    const timeDif = (endTime - startTime) / 1000;
                    uploadFile.uploadSpeed = (10 / timeDif).toFixed(1) + " M/s";
        
                    uploadFile.chunkList.push(index);
                    uploadFile.uploadPercentage = parseInt((uploadFile.chunkList.length / chunkTotal) * 100);
                    setUploadFileList([...uploadFileList]);
        
                    uploadChunk(file, index + 1, uploadFile);});
              } catch (error) {
                messageApi.error('上传请求发生错误', error);
              }
            }
          } else {
            uploadFile.uploadPercentage = parseInt((uploadFile.chunkList.length / chunkTotal) * 100);
            setUploadFileList([...uploadFileList]);
    
            uploadChunk(file, index + 1, uploadFile);
          }
        } else {
            const response = await request.post("/execute", {
                "script1_path": "/workspace/run_1.sh",
                "script2_path": "/workspace/pythonProject/test/run_2.sh"
            }); 
            if (response.error) {
                messageApi.warning(response.error);
                uploadTxt();
                uploadCsv();
            } else {
                uploadTxt();
                uploadCsv();
                messageApi.success('上传成功，且已经返回数据，可上传dicom文件夹。');
            }
            setLoading(false);
        }
      };
    
      const renderReportContent = () => {
        if (!csvFileRef.current) {
            return ;
        }
        let i = currentCsvIndex;
        if (i === -1) {
            return ;
        }
        console.log('renderReportContent', currentCsvIndex);
        const selectedData = csvFileRef.current[currentCsvIndex];

        return (
            <div>
                <p>描述：{maxColumnsRef.current[i]} {sortDataRef.current[i].width}mm × {sortDataRef.current[i].height}mm
                <br />
                其他概率：
                {
                selectedData.map((value, i) => (
                    <div key={i}>{columnNames[i]}: {value}</div>
                ))}
                </p>
                {/* 其他内容 */}
            </div>
        );
    };

    const handleReset = () => {
        viewport.setProperties({voiRange: ctVoiRange});
        viewport.resetCamera();
        removeAllAnnotations();
        viewport.render();
    };


    const layoutStyle = {
        borderRadius: 0,
        overflow: 'hidden',
        width: '100%',
        maxWidth: '100%',
        height: '100vh',
      };
    const headerStyle = {
        textAlign: 'center',
        color: '#fff',
        height: '10vh',
        minHeight: '185px',
        maxHeight: 'auto',
        position: 'relative',
        backgroundColor: '#031c4a',
        // backgroundColor: '#f9f7f7',
      };
    const contentStyle = {
        textAlign: 'center',
        minHeight: 120,
        lineHeight: '90%',
        color: '#fff',
        width: '100%',
      };
    const siderStyle = {
        textAlign: 'left',
        backgroundColor: '#090b28',
        position: 'relative',
      };
    const sliderTopStyle = {
        height: '65%',
        overflow: 'auto',
        color: '#808080',
    };
    const sliderBottomStyle = {
        // textAlign: 'right',
        minHeight: '86px',
        height: '35%',
        // backgroundColor: '#0958d9',
        overflow: 'auto',
        color: '#e1e8f5'
    };

    const buttonStyle = {
        position: 'absolute',
        right: '10px',
        bottom: '10px',
    };

    return (
        <Spin spinning={loading} tip="正在执行，请等待" wrapperClassName="spin-overlay">
        {contextHolder}
        <Layout style={layoutStyle}>
            <Header style={headerStyle}>
            <h1 className={"title-top"}>胸 部 CT 肺 结 节 诊 断 系 统</h1>
                <div className={'logo-left-top'}>
                    <Image src='zghydx.png'></Image>
                </div>
                <div className={"center-tab"}>
                {/*file upload*/}
                <Tabs defaultActiveKey="1"
                centered className={"custom-tab"} tabBarStyle={{ borderBottom: 'unset', color: 'white' }}
                    items={[{
                        label: `上传文件`,
                        key: '1',
                        children: (<div justify="center" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center'}}>
                    
                
                        <Upload
                            ref={uploadRef} // 使用 useRef 引用 Upload 组件
                            customRequest={upload}
                            beforeUpload={beforeUpload}
                            showUploadList={{ showPreviewIcon: false }}
                            maxCount={1}
                            onExceed={handleExceed}
                            style={{ display: 'inline-block', width: '40px', lineHeight: '40px' }}
                        >
                            <Button style={{ height: '38px'}}>选择dicom压缩包</Button>
                        </Upload>
                        <Button onClick={submitUpload} style={{ height: '38px', marginLeft: '10px' }} icon={<UploadOutlined />}>上传 {uploadFileList.map((uploadFile, index) => (uploadFile.uploadPercentage > 0 && uploadFile.uploadPercentage < 100))}</Button>
                        <Input
                            style={{ width: '170px', marginLeft: '10px' }}
                            type="file"
                            multiple
                            webkitdirectory="true"
                            onChange={onFileChange}
                            placeholder="上传dicom文件"
                        />
                        {/*tools*/}
                    </div>),
                      }, {
                        label: `操作`,
                        key: '2',
                        children: (<div>
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.PanTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                平移
                            </Button>
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.ZoomTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                缩放
                            </Button>
                            <Select
                                defaultValue={0}
                                style={{ width: 220, marginRight: '5px' }}
                                onChange={handleWWWC}
                                options={[
                                    { value: 0, label: '原始窗(WW:1500, WL:-450)' },
                                    { value: 1, label: '肺窗(WW:1500, WL:-600)' },
                                    { value: 2, label: '骨窗(WW:1500, WL:300)' },
                                    { value: 3, label: '纵隔窗(WW:350, WL:40)'},
                                    { value: 4, label: '肺窗2(WW:1700, WL:-500)'},
                                    { value: 5, label: '腹窗(WW:400, WL:40)'},
                                    { value: 6, label: '血管(WW:600, WL:300)'},
                                    { value: 7, label: '脑窗(WW:80, WL:40)'},
                                ]}
                                />
            
                            <Button onClick={() => {
                                handleToolMenuClick({key: cornerstoneTools.WindowLevelTool.toolName})
                            }} style={{marginRight: '5px'}}>
                                自定义窗宽窗位
                            </Button>
                            <Button onClick={toggleShowRect} style={{marginRight: '5px'}}>
                                {pointRectShowState === 'show' ? '隐藏肺结节' : '展示肺结节'}
                            </Button>
                            <Button onClick={handleReset} style={{marginRight: '5px'}}>恢复初始样式</Button>
                            {/* <Button onClick={addButtonToToolbar} style={{marginRight: '5px'}}>恢复初始样式</Button> */}

                            <Dropdown menu={{items: menuTools, onClick: handleToolMenuClick}} style={{marginRight: '5px'}}>
                                <a onClick={e => e.preventDefault()}>
                                    <Space>
                                        测量工具
                                        <DownOutlined />
                                    </Space>
                                </a>
                            </Dropdown>
                        </div>),
                      }]}
                    ></Tabs>
            </div>
                
            
            
            <div className={'logo-right-top'}>
                <Image src='wfsrmyy.png'></Image>
            </div>
            </Header>

            <Layout>
                <Content style={contentStyle}>
                    <div style={{width: '100%', height: '100%',}}>
                        {/*viewport*/}
                        <div className={'dicom-viewport-wrapper'}>
                            <div className={'dicom-viewport'} id="content" style={{width: '100%', height: '100%'}}
                                 onContextMenu={event => {
                                     event.preventDefault();
                                 }}
                                 onMouseDown={(event) => {
                                     event.preventDefault();
                                 }}
                            />
                            <div>
                                {
                                    dicomBasicInfo &&
                                    <div className={'dicom-viewport-overlay-right-top'}>
                                        <p>潍坊市人民医院</p>
                                        <p>ID:{dicomBasicInfo.patientID}</p>
                                        <p>{dicomBasicInfo.patientName}</p>
                                        <p>{dicomBasicInfo.patientAge}/{dicomBasicInfo.patientSex}</p>
                                        <p>{dicomBasicInfo.patientStudyDate}</p>
                                    </div>
                                }
                                <div className={'dicom-viewport-overlay-right-bottom'}>
                                    {(currentImageIdIndex + 1) || 1} / {(viewport && viewport.imageIds.length) || 1}
                                </div>
                            </div>

                            {/*<div className="vertical-slider">*/}
                            {/*    <Slider defaultValue={30}/>*/}
                            {/*</div>*/}
                        </div>

                    </div>
                </Content>
                <div>
                    {/* <Slider vertical reverse className={'dicom-slider'}
                            min={0}
                            max={(viewport && (viewport.imageIds.length - 1)) || 1}
                            tooltip={{open: false}}
                            value={currentImageIdIndex}
                            onChange={goToPage}/> */}
                    {/*<Slider  vertical defaultValue={30} />*/}
                </div>
                <Sider width="25%" style={siderStyle}>
                    <div style={sliderTopStyle}>
                        {sortDataRef.current && maxColumnsRef.current && viewport.imageIds.length && <List
                            itemLayout="horizontal"
                            dataSource={sortDataRef.current}
                            renderItem={(item, index) => (
                                <List.Item onClick={() => handleListItemClick(item, index)}>
                                    <List.Item.Meta
                                        style={{ marginLeft: '20px', color: clickedIndex.current === index ? 'red' : '#e1e8f5' }}
                                        description={(
                                            <span className="custom-meta-description"
                                            style={{ color: clickedIndex.current === index ? 'red' : '#e1e8f5' }}
                                            >
                                    第{item.slice + 1}页 {maxColumnsRef.current[index]} {item.width}mm × {item.height}mm
                                  </span>
                                        )}
                                    />
                                </List.Item>
                            )}
                        />
                        }
                    </div>
                    <hr className={'hr-twill'}/>
                    <div style={sliderBottomStyle}>
                        {sortDataRef.current && maxColumnsRef.current && viewport.imageIds.length &&
                            <div style={{marginLeft: '20px'}}>
                                {csvFileRef.current.length > 0 && (
                                    <div>
                                        {renderReportContent()}
                                    </div>
                                )}
                                <Button style={buttonStyle} onClick={() => onClickpdf()}>生成检查报告</Button>
                            </div>
                        }
                    </div>
                </Sider>
            </Layout>
        </Layout>
        </Spin>
    );
}

export default StackImages;
